package com.example.oauth2.service;

import com.example.oauth2.entry.Client;
import com.example.oauth2.repository.ClientRepository;
import com.example.oauth2.util.APIResponse;
import com.example.oauth2.vo.ClientVO;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;


@Component
public class ClientService {

    private Logger logger = LogManager.getLogger(getClass());

    @Autowired
    private ClientRepository clientRepository;
    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();


    public APIResponse addClient(ClientVO clientVO) {
        APIResponse apiResponse = new APIResponse();
        apiResponse.setResponseCode(APIResponse.OK);

        //此处忽略重复用户校验

        try {
            Client client = new Client();
            client.setClientId(clientVO.getClientId());
            client.setClientSecret(passwordEncoder.encode(clientVO.getClientSecret()));
            client.setResourceId(clientVO.getResourceId());
            client.setScope(clientVO.getScope());
            client.setAuthorizedGrantTypes(clientVO.getAuthorizedGrantTypes());
            client.setRegisteredRedirectUri(clientVO.getRegisteredRedirectUri());
            client.setAccessTokenValiditySeconds(clientVO.getAccessTokenValiditySeconds());
            client.setRefreshTokenValiditySeconds(clientVO.getRefreshTokenValiditySeconds());
            client.setAuthorities(clientVO.getAuthorities());
            client.setAdditionalInformation(clientVO.getAdditionalInformation());
            clientRepository.save(client);
        } catch (Exception e) {
            Throwable t = Optional.ofNullable(e.getCause()).orElse(e);
            String errorMessage = Optional.ofNullable(t.getMessage()).orElse("Internal exception: " + e);
            String traceMessage = Arrays.asList(e.getStackTrace()).stream().map(trace -> trace.toString()).collect(Collectors.joining("\nat "));
            logger.log(Level.ERROR, errorMessage + "\nat " + traceMessage);
            apiResponse.setResponseCode(APIResponse.ERROR);
        }
        return apiResponse;
    }

}
